﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Admin.Models.ConfigManager;
using Zocono.WCS.Admin.Models.User;
using Zocono.WCS.Application.AppConfigureManage;
using Zocono.WCS.Application.AppTraces;
using Zocono.WCS.Infrastructure.ApllicationDto.DtoWcsManage;

namespace Zocono.WCS.Admin.Controllers.ConfigManageMoudle
{
    public class PlcReadDBController : BaseController
    {
        private readonly PlcReadDbInfoApp _plcReadDbInfoApp;
        private readonly PlcWriteDbInfoApp _plcWriteDbInfoApp;
        private readonly BytesMapObjectInfoApp _bytesMapObjectInfoApp;
        private readonly JobInfoApp _jobInfoApp;
        private readonly PlcConnectionInfoApp _plcConnectionInfoApp;

        public PlcReadDBController(PlcReadDbInfoApp plcReadDbInfoApp, PlcWriteDbInfoApp plcWriteDbInfoApp, BytesMapObjectInfoApp bytesMapObjectInfoApp, JobInfoApp jobInfoApp, PlcConnectionInfoApp plcConnectionInfoApp, IMemoryCache memoryCache, TracesApp tracesApp, IHttpContextAccessor httpContextAccessor) : base(memoryCache, tracesApp, httpContextAccessor)
        {
            this._plcReadDbInfoApp = plcReadDbInfoApp;
            this._plcWriteDbInfoApp = plcWriteDbInfoApp;
            this._bytesMapObjectInfoApp = bytesMapObjectInfoApp;
            this._jobInfoApp = jobInfoApp;
            this._plcConnectionInfoApp = plcConnectionInfoApp;
        }

        public IActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 封装用于下拉列表的数据
        /// </summary>
        /// <returns></returns>
        public async Task<PlcReadDbSearchPageData> GetPlcSearchDataAsync()
        {
            var plcPageSearchData = new PlcReadDbSearchPageData();
            //通过jobName ID 搜索数据list
            plcPageSearchData.JobSearchs = new List<PlcJobSearchPageData>();
            var jobs = await _jobInfoApp.GetJobInfoListAsync();
            if (jobs != null && jobs.Count > 0)
            {
                foreach (var job in jobs)
                {
                    plcPageSearchData.JobSearchs.Add(new PlcJobSearchPageData() { JobId = job.ID.ToString(), JobName = job.JobName });
                }
            }
            //通过 IP 去搜索
            var plcIps = await _plcConnectionInfoApp.GetPlcConnectionInfoAsync();
            plcPageSearchData.PlcIpSearchs = new List<PlcIPSearchPageData>();
            if (plcIps != null && plcIps.Count > 0)
            {
                foreach (var plcIp in plcIps)
                {
                    plcPageSearchData.PlcIpSearchs.Add(new PlcIPSearchPageData() { PlcConnectId = plcIp.ID.ToString(), PlcConnectIp = plcIp.IP, ScEquipmentCode=plcIp.ScEquipmentCode });
                }
            }
            return plcPageSearchData;
        }

        /// <summary>
        /// plc读取数据列表页面
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> PlcReadDBInfoAsync()
        {
            var plcPageSearchData = await GetPlcSearchDataAsync();
            //await AddTracesInfo();
            return View(plcPageSearchData);
        }

        public async Task<JsonResult> GetAllPlcReadDBInfoAsync()
        {
            var where = new QueryPlcReadDbInfoDto();
            where.PageIndex = (Start / Length) + 1;
            where.PageSize = Length;
            where.PlcName = Request.Form["plcName"].ToString();
            where.ProcessModuleName = Request.Form["moduleName"].ToString();
            where.DbCode = Request.Form["DBCode"].ToInt32();
            where.JobID = Request.Form["jobId"].ToInt64();
            where.PlcConnectionID = Request.Form["ipSearch"].ToInt64();
            where.EquipmentCode= Request.Form["equipmentCode"].ToString();
            var plcReadList = await _plcReadDbInfoApp.GetPlcReadDbInfoAsync(where);
            //处理cpuType名称显示
            foreach (var plcRead in plcReadList.Result)
            {
                var result = plcRead.PlcCpuType.ToString();
                var item = S7CpuTypeItem.S7CpuTypeDatasource.FirstOrDefault(c => c.CpuTypeValue == plcRead.PlcCpuType.ToInt32());
                if (item != null)
                {
                    result = item.CpuTypeName;
                }
                plcRead.PlcCpuTypeName = result;
            }
            var pageData = new TableData<PlcReadDbInfoDto>(Draw, plcReadList.Total, plcReadList.Total, plcReadList.Result);

            //await AddTracesInfo(5, 0, "获取PLCReadDB数据列表"); 
            
            return Json(pageData);
        }

        public async Task<ActionResult> PlcReadDbInfoAddOrEditAsync(long id)
        {
            var pageData = await GetPlcSearchDataAsync();
            if (id > 0)
            {
                var plcReadInfoData = await _plcReadDbInfoApp.GetPlcReadDbInfoByIDAsync(id);
                pageData.ID = plcReadInfoData.ID;
                pageData.JobID = plcReadInfoData.JobID;
                pageData.DbCode = plcReadInfoData.DbCode;
                pageData.EquipmentCode = plcReadInfoData.EquipmentCode;
                pageData.DbLength = plcReadInfoData.DbLength;
                pageData.DbStart = plcReadInfoData.DbStart;
                pageData.IsEnable = plcReadInfoData.IsEnable;
                pageData.IsHeartbeat = plcReadInfoData.IsHeartbeat;
                pageData.PlcName = plcReadInfoData.PlcName;
                pageData.PlcConnectionID = plcReadInfoData.PlcConnectionID;
                pageData.ProcessModuleName = plcReadInfoData.ProcessModuleName;
                pageData.ProcessModuleType = plcReadInfoData.ProcessModuleType;
            }

            return View(pageData);
        }
        /// <summary>
        /// 添加和编辑读取DB操作
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResult> OperatePlcReadDBInfoAsync()
        {
            var plcReadDbInfoDto = new PlcReadDbInfoDto();
            plcReadDbInfoDto.ID = Request.Form["id"].ToInt64();
            plcReadDbInfoDto.PlcName = Request.Form["PlcName"].ToString();
            plcReadDbInfoDto.EquipmentCode = Request.Form["EquipmentCode"].ToString();
            plcReadDbInfoDto.DbCode = Request.Form["DbCode"].ToInt32();
            plcReadDbInfoDto.DbStart = Request.Form["DbStart"].ToInt32();
            plcReadDbInfoDto.DbLength = Request.Form["DbLength"].ToInt32();
            plcReadDbInfoDto.ProcessModuleType = Request.Form["ProcessModuleType"].ToString();
            plcReadDbInfoDto.ProcessModuleName = Request.Form["ProcessModuleName"].ToString();
            plcReadDbInfoDto.JobID = Request.Form["JobID"].ToInt64();
            plcReadDbInfoDto.PlcConnectionID = Request.Form["PlcConnectionID"].ToInt64();
            plcReadDbInfoDto.IsHeartbeat = Request.Form["IsHeartbeat"].ToBool();
            plcReadDbInfoDto.IsEnable = Request.Form["IsEnable"].ToBool();

            bool result;
            string msg;
            try
            {
                if(plcReadDbInfoDto.ID == 0)
                {
                    var res = await _plcReadDbInfoApp.AddPlcReadDbInfoAsync(plcReadDbInfoDto);
                    await AddTracesInfo(2, 0, "新增PLC读取DB配置");
                    result = res > 0;
                }
                else
                {
                    result = await _plcReadDbInfoApp.UpdatePlcReadDbInfoAsync(plcReadDbInfoDto);
                    await AddTracesInfo(3, 0, "修改PLC读取DB配置");
                }
                msg = result ? "成功" : "失败";
            }
            catch (Exception e)
            {
                result = false;
                msg = e.Message;
            }

            return CreateJsonGetResult(result, msg);
        }
        /// <summary>
        /// 删除plc读取DB配置
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResult> DelPlcReadDBInfoAsync()
        {
            var id = Request.Form["id"].ToInt64();
            bool result;
            string msg;
            try
            {
                result = await _plcReadDbInfoApp.DeletePlcReadDbInfoAsync(id);
                msg = result ? "成功" : "失败";
            }
            catch (Exception e)
            {
                result = false;
                msg = e.Message;
            }
            await AddTracesInfo(4, 0, "PLC读取DB配置删除");
            return CreateJsonGetResult(result, msg);
        }

        /// <summary>
        /// 新增DB配置
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ActionResult> PlcReadDbInfoAddMoreAsync(long id)
        {
            var pageData = await GetPlcSearchDataAsync();
            if (id > 0)
            {
                var plcReadInfoData = await _plcReadDbInfoApp.GetPlcReadDbInfoByIDAsync(id);
                pageData.ID = plcReadInfoData.ID;
                pageData.JobID = plcReadInfoData.JobID;
                pageData.DbCode = plcReadInfoData.DbCode;
                pageData.EquipmentCode = plcReadInfoData.EquipmentCode;
                pageData.DbLength = plcReadInfoData.DbLength;
                pageData.DbStart = plcReadInfoData.DbStart;
                pageData.IsEnable = plcReadInfoData.IsEnable;
                pageData.IsHeartbeat = plcReadInfoData.IsHeartbeat;
                pageData.PlcName = plcReadInfoData.PlcName;
                pageData.PlcConnectionID = plcReadInfoData.PlcConnectionID;
                pageData.ProcessModuleName = plcReadInfoData.ProcessModuleName;
                pageData.ProcessModuleType = plcReadInfoData.ProcessModuleType;
            }

            return View(pageData);
        }

        /// <summary>
        /// 添加DB配置及解析
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResult> AddPlcReadDBInfoAndMoreAsync()
        {
            //PLC读
            var plcReadDbInfoDtoPlc = new PlcReadDbInfoDto();
            plcReadDbInfoDtoPlc.ID = Request.Form["id"].ToInt64();
            plcReadDbInfoDtoPlc.PlcName = Request.Form["PlcName"].ToString() + "PLC";
            plcReadDbInfoDtoPlc.EquipmentCode = Request.Form["EquipmentCode"].ToString();
            plcReadDbInfoDtoPlc.DbCode = Request.Form["DbCode"].ToInt32();
            plcReadDbInfoDtoPlc.DbStart = Request.Form["DbStart"].ToInt32();
            plcReadDbInfoDtoPlc.DbLength = Request.Form["DbLength"].ToInt32();
            plcReadDbInfoDtoPlc.ProcessModuleType = Request.Form["ProcessModuleType"].ToString();
            plcReadDbInfoDtoPlc.ProcessModuleName = Request.Form["ProcessModuleName"].ToString();
            plcReadDbInfoDtoPlc.JobID = Request.Form["JobID"].ToInt64();
            plcReadDbInfoDtoPlc.PlcConnectionID = Request.Form["PlcConnectionID"].ToInt64();
            plcReadDbInfoDtoPlc.IsHeartbeat = Request.Form["IsHeartbeat"].ToBool();
            plcReadDbInfoDtoPlc.IsEnable = Request.Form["IsEnable"].ToBool();

            //WCS读
            var plcReadDbInfoDtoWcs = new PlcReadDbInfoDto();
            plcReadDbInfoDtoWcs.ID = Request.Form["id"].ToInt64();
            plcReadDbInfoDtoWcs.PlcName = Request.Form["PlcName"].ToString() + "WCS";
            plcReadDbInfoDtoWcs.EquipmentCode = Request.Form["EquipmentCode"].ToString();
            plcReadDbInfoDtoWcs.DbCode = Request.Form["DbCode2"].ToInt32();
            plcReadDbInfoDtoWcs.DbStart = Request.Form["DbStart"].ToInt32();
            plcReadDbInfoDtoWcs.DbLength = Request.Form["DbLength"].ToInt32();
            plcReadDbInfoDtoWcs.ProcessModuleType = Request.Form["ProcessModuleType"].ToString();
            plcReadDbInfoDtoWcs.ProcessModuleName = Request.Form["ProcessModuleName"].ToString();
            plcReadDbInfoDtoWcs.JobID = Request.Form["JobID"].ToInt64();
            plcReadDbInfoDtoWcs.PlcConnectionID = Request.Form["PlcConnectionID"].ToInt64();
            plcReadDbInfoDtoWcs.IsHeartbeat = Request.Form["IsHeartbeat"].ToBool();
            plcReadDbInfoDtoWcs.IsEnable = Request.Form["IsEnable"].ToBool();

            //WCS写
            var plcWriteDbInfoDto = new PlcWriteDbInfoDto();
            plcWriteDbInfoDto.ID = Request.Form["id"].ToInt64();
            plcWriteDbInfoDto.EquipmentCode = Request.Form["EquipmentCode"].ToString();
            plcWriteDbInfoDto.DbCode = Request.Form["DbCode2"].ToInt32();
            plcWriteDbInfoDto.DbStart = Request.Form["DbStart"].ToInt32();
            plcWriteDbInfoDto.ObjectType = Request.Form["ObjectType"].ToString();
            plcWriteDbInfoDto.PlcConnectionId = Request.Form["PlcConnectionID"].ToInt64();
            bool result = false;
            string msg;
            try
            {
                if (!string.IsNullOrEmpty(plcWriteDbInfoDto.ObjectType))
                {
                    var wID = await _plcWriteDbInfoApp.AddPlcWriteDbInfoAsync(plcWriteDbInfoDto);
                    if (wID == 0)
                    {
                        return CreateJsonGetResult(result, "WCS写配置写入失败！");
                    }
                }
                var plcRID = await _plcReadDbInfoApp.AddPlcReadDbInfoAsync(plcReadDbInfoDtoPlc);
                if (plcRID > 0)
                {
                    var bytesMapObjectInfoDtoplc = new BytesMapObjectInfoDto();
                    bytesMapObjectInfoDtoplc.ID = Request.Form["id"].ToInt64();
                    bytesMapObjectInfoDtoplc.ObjectName = Request.Form["PLCobjectName"].ToString();
                    bytesMapObjectInfoDtoplc.PlcReadDbId = plcRID;
                    bytesMapObjectInfoDtoplc.ObjectLength = Request.Form["objectLength"].ToInt32();
                    bytesMapObjectInfoDtoplc.BytesIndex = Request.Form["BytesIndex"].ToInt32();
                    bytesMapObjectInfoDtoplc.BytesLength = Request.Form["DbLength"].ToInt32();
                    bytesMapObjectInfoDtoplc.EquipmentCode = "0";
                    await _bytesMapObjectInfoApp.AddBytesMapObjectInfoAsync(bytesMapObjectInfoDtoplc);
                }
                else
                {
                    return CreateJsonGetResult(result, "PLC读配置写入失败！");
                }
                if (!string.IsNullOrEmpty(plcReadDbInfoDtoWcs.ProcessModuleName))
                {
                    var wcsRID = await _plcReadDbInfoApp.AddPlcReadDbInfoAsync(plcReadDbInfoDtoWcs);
                    if (wcsRID > 0)
                    {
                        var bytesMapObjectInfoDtowcs = new BytesMapObjectInfoDto();
                        bytesMapObjectInfoDtowcs.ID = Request.Form["id"].ToInt64();
                        bytesMapObjectInfoDtowcs.ObjectName = Request.Form["WCSobjectName"].ToString();
                        bytesMapObjectInfoDtowcs.PlcReadDbId = wcsRID;
                        bytesMapObjectInfoDtowcs.ObjectLength = Request.Form["objectLength"].ToInt32();
                        bytesMapObjectInfoDtowcs.BytesIndex = Request.Form["BytesIndex"].ToInt32();
                        bytesMapObjectInfoDtowcs.BytesLength = Request.Form["DbLength"].ToInt32();
                        bytesMapObjectInfoDtowcs.EquipmentCode = "0";
                        await _bytesMapObjectInfoApp.AddBytesMapObjectInfoAsync(bytesMapObjectInfoDtowcs);
                    }
                    else
                    {
                        return CreateJsonGetResult(result, "WCS读配置写入失败！");
                    }
                }
                await AddTracesInfo(2, 0, "新增DB配置AddPlcReadDBInfoAndMoreAsync");

                result = true;
                msg = result ? "成功" : "失败";
            }
            catch (Exception e)
            {
                result = false;
                msg = e.Message;
            }

            return CreateJsonGetResult(result, msg);
        }

        /// <summary>
        /// 导入excel表添加DB配置
        /// </summary>
        /// <param name="fileDatas"></param>
        /// <returns></returns>
        public async Task<JsonResult> AddPlcReadDBInfoByFilesAsync([FromBody]List<FileUploadDBData> fileDatas)
        {
            bool result = false;
            string msg = "失败！";
            if (fileDatas != null && fileDatas.Count > 0)
            {
                try
                {
                    foreach (var item in fileDatas)
                    {
                        //通过作业名获取作业
                        var jobInfo = await _jobInfoApp.GetJobInfoByJobNameAsync(item.JobID);
                        if (jobInfo == null)
                        {
                            return CreateJsonGetResult(result, "作业未配置！" + item.JobID);
                        }
                        var pclConnectInfo = await _plcConnectionInfoApp.GetPlcConnectionInfoByIpAsync(item.PlcConnectionID);
                        if (pclConnectInfo == null)
                        {
                            return CreateJsonGetResult(result, "IP未配置！" + item.PlcConnectionID);
                        }
                        //PLC读
                        var plcReadDbInfoDtoPlc = new PlcReadDbInfoDto();
                        plcReadDbInfoDtoPlc.ID = 0;
                        plcReadDbInfoDtoPlc.PlcName = item.PlcName + "PLC";
                        plcReadDbInfoDtoPlc.EquipmentCode = item.EquipmentCode.ToString();
                        plcReadDbInfoDtoPlc.DbCode = item.DbCode.ToInt32();
                        plcReadDbInfoDtoPlc.DbStart = item.DbStart.ToInt32();
                        plcReadDbInfoDtoPlc.DbLength = item.DbLength.ToInt32();
                        plcReadDbInfoDtoPlc.ProcessModuleType = item.ProcessModuleType?.ToString();
                        plcReadDbInfoDtoPlc.ProcessModuleName = item.ProcessModuleName?.ToString();
                        plcReadDbInfoDtoPlc.JobID = jobInfo.ID.ToInt64();
                        plcReadDbInfoDtoPlc.PlcConnectionID = pclConnectInfo.ID.ToInt64();
                        plcReadDbInfoDtoPlc.IsHeartbeat = item.IsHeartbeat.ToBool();
                        plcReadDbInfoDtoPlc.IsEnable = item.IsEnable.ToBool();

                        //WCS读
                        var plcReadDbInfoDtoWcs = new PlcReadDbInfoDto();
                        plcReadDbInfoDtoWcs.ID = 0;
                        plcReadDbInfoDtoWcs.PlcName = item.PlcName.ToString() + "WCS";
                        plcReadDbInfoDtoWcs.EquipmentCode = item.EquipmentCode.ToString();
                        plcReadDbInfoDtoWcs.DbCode = item.DbCode2.ToInt32();
                        plcReadDbInfoDtoWcs.DbStart = item.DbStart.ToInt32();
                        plcReadDbInfoDtoWcs.DbLength = item.DbLength.ToInt32();
                        plcReadDbInfoDtoWcs.ProcessModuleType = item.ProcessModuleType?.ToString();
                        plcReadDbInfoDtoWcs.ProcessModuleName = item.ProcessModuleNameWcs?.ToString();
                        plcReadDbInfoDtoWcs.JobID = jobInfo.ID.ToInt64();
                        plcReadDbInfoDtoWcs.PlcConnectionID = pclConnectInfo.ID.ToInt64();
                        plcReadDbInfoDtoWcs.IsHeartbeat = item.IsHeartbeat.ToBool();
                        plcReadDbInfoDtoWcs.IsEnable = item.IsEnable.ToBool();

                        //WCS写
                        var plcWriteDbInfoDto = new PlcWriteDbInfoDto();
                        plcWriteDbInfoDto.ID = 0;
                        plcWriteDbInfoDto.EquipmentCode = item.EquipmentCode.ToString();
                        plcWriteDbInfoDto.DbCode = item.DbCode2.ToInt32();
                        plcWriteDbInfoDto.DbStart = item.DbStart.ToInt32();
                        plcWriteDbInfoDto.ObjectType = item.ObjectType?.ToString();
                        plcWriteDbInfoDto.PlcConnectionId = pclConnectInfo.ID.ToInt64();

                        //插入写DB配置
                        if (!string.IsNullOrEmpty(plcWriteDbInfoDto.ObjectType))
                        {
                            var wID = await _plcWriteDbInfoApp.AddPlcWriteDbInfoAsync(plcWriteDbInfoDto);
                            if (wID == 0)
                            {
                                return CreateJsonGetResult(result, "WCS写配置写入失败！" + item.EquipmentCode);
                            }
                        }
                        //wcs读配置
                        //var wcsObjextType = item.WCSobjectName?.ToString();
                        if (!string.IsNullOrEmpty(item.WCSobjectName) && !string.IsNullOrEmpty(plcReadDbInfoDtoWcs.ProcessModuleName))
                        {
                            //插入wcs读数据
                            var wcsRID = await _plcReadDbInfoApp.AddPlcReadDbInfoAsync(plcReadDbInfoDtoWcs);
                            if (wcsRID > 0)
                            {
                                //插入wcs读数据解析
                                var bytesMapObjectInfoDtowcs = new BytesMapObjectInfoDto();
                                bytesMapObjectInfoDtowcs.ID = 0;
                                bytesMapObjectInfoDtowcs.ObjectName = item.WCSobjectName.ToString();
                                bytesMapObjectInfoDtowcs.PlcReadDbId = wcsRID;
                                bytesMapObjectInfoDtowcs.ObjectLength = item.objectLength.ToInt32();
                                bytesMapObjectInfoDtowcs.BytesIndex = item.BytesIndex.ToInt32();
                                bytesMapObjectInfoDtowcs.BytesLength = item.DbLength.ToInt32();
                                bytesMapObjectInfoDtowcs.EquipmentCode = "0";
                                await _bytesMapObjectInfoApp.AddBytesMapObjectInfoAsync(bytesMapObjectInfoDtowcs);
                            }
                            else
                            {
                                return CreateJsonGetResult(result, "WCS读配置写入失败！" + item.EquipmentCode);
                            }
                        }
                        if (!string.IsNullOrEmpty(item.PLCobjectName) && !string.IsNullOrEmpty(plcReadDbInfoDtoPlc.ProcessModuleName))
                        {
                            //插入plc读数据
                            var plcRID = await _plcReadDbInfoApp.AddPlcReadDbInfoAsync(plcReadDbInfoDtoPlc);
                            if (plcRID > 0)
                            {
                                //插入plc读数据解析
                                var bytesMapObjectInfoDtoplc = new BytesMapObjectInfoDto();
                                bytesMapObjectInfoDtoplc.ID = 0;
                                bytesMapObjectInfoDtoplc.ObjectName = item.PLCobjectName.ToString();
                                bytesMapObjectInfoDtoplc.PlcReadDbId = plcRID;
                                bytesMapObjectInfoDtoplc.ObjectLength = item.objectLength.ToInt32();
                                bytesMapObjectInfoDtoplc.BytesIndex = item.BytesIndex.ToInt32();
                                bytesMapObjectInfoDtoplc.BytesLength = item.DbLength.ToInt32();
                                bytesMapObjectInfoDtoplc.EquipmentCode = "0";
                                await _bytesMapObjectInfoApp.AddBytesMapObjectInfoAsync(bytesMapObjectInfoDtoplc);
                            }
                            else
                            {
                                return CreateJsonGetResult(result, "PLC读配置写入失败！" + item.EquipmentCode);
                            }
                        }
                    }
                    result = true;
                    msg = "添加配置成功";
                }
                catch (Exception ex)
                {

                    result = false;
                    msg = ex.Message;
                }
            }
            return CreateJsonGetResult(result, msg);
        }


    }
}
